#include "led_driver.h"
#include "esp_log.h"

#define TAG "LED_DRIVER"

static led_control_t leds[2];
static TaskHandle_t led_task_handle = NULL;

static void process_led_state(led_type_t led, gpio_num_t gpio);

static void led_task(void *arg) {
    const TickType_t interval = pdMS_TO_TICKS(10); // 10ms周期
    TickType_t last_wake = xTaskGetTickCount();

    while (1) {
        process_led_state(LED_NET_STATE, NET_LED_GPIO);
        process_led_state(LED_GPS_STATE, GPS_LED_GPIO);
        vTaskDelayUntil(&last_wake, interval);
    }
}

static void process_led_state(led_type_t led, gpio_num_t gpio) {
    led_control_t *ctl = &leds[led];

    switch (ctl->state) {
        case LED_SLOW_BLINK:
            if (xTaskGetTickCount() - ctl->last_toggle >= pdMS_TO_TICKS(500)) {
                ctl->current_level = !ctl->current_level;
                ledc_set_duty(LEDC_MODE, ctl->channel, ctl->current_level ? (1 << LEDC_DUTY_RES) - 1 : 0);
                ledc_update_duty(LEDC_MODE, ctl->channel);
                ctl->last_toggle = xTaskGetTickCount();
            }
            break;

        case LED_FAST_BLINK:
            if (xTaskGetTickCount() - ctl->last_toggle >= pdMS_TO_TICKS(1000)) {
                ctl->current_level = !ctl->current_level;
                ledc_set_duty(LEDC_MODE, ctl->channel, ctl->current_level ? (1 << LEDC_DUTY_RES) - 1 : 0);
                ledc_update_duty(LEDC_MODE, ctl->channel);
                ctl->last_toggle = xTaskGetTickCount();
                ESP_LOGI(TAG, "ctl->last_toggle:%ld,ctl->current_level:%d", ctl->last_toggle, ctl->current_level);
            }
            break;

        case LED_ON:
            ledc_set_duty(LEDC_MODE, ctl->channel, (1 << LEDC_DUTY_RES) - 1); // 最大占空比，灯亮
            ledc_update_duty(LEDC_MODE, ctl->channel);
            break;

        case LED_BREATH:
            if (xTaskGetTickCount() - ctl->last_toggle >= pdMS_TO_TICKS(10)) {
                ctl->breath_duty += ctl->breath_direction * 100; // 调整步长
                if (ctl->breath_duty >= (1 << LEDC_DUTY_RES) - 1) {
                    ctl->breath_duty = (1 << LEDC_DUTY_RES) - 1;
                    ctl->breath_direction = -1;
                } else if (ctl->breath_duty <= 0) {
                    ctl->breath_duty = 0;
                    ctl->breath_direction = 1;
                }
                ledc_set_duty(LEDC_MODE, ctl->channel, ctl->breath_duty);
                ledc_update_duty(LEDC_MODE, ctl->channel);
                ctl->last_toggle = xTaskGetTickCount();
            }
            break;

        default: // LED_OFF
            ledc_set_duty(LEDC_MODE, ctl->channel, 0); // 占空比为0，灯灭
            ledc_update_duty(LEDC_MODE, ctl->channel);
            break;
    }
}

void led_init(void) {
    // 初始化GPIO
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << NET_LED_GPIO) | (1ULL << GPS_LED_GPIO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉
        .intr_type = GPIO_INTR_DISABLE
    };
    gpio_config(&io_conf);

    // 设置默认电平为高（关闭LED）
    gpio_set_level(NET_LED_GPIO, 1);
    gpio_set_level(GPS_LED_GPIO, 1);

    // 配置PWM定时器
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_DUTY_RES,
        .freq_hz = LEDC_FREQUENCY,
        .speed_mode = LEDC_MODE,
        .timer_num = LEDC_TIMER
    };
    if (ledc_timer_config(&ledc_timer) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to configure PWM timer");
        return;
    }

    // 配置PWM通道
    ledc_channel_config_t ledc_channel_net = {
        .channel    = LEDC_CHANNEL_NET,
        .duty       = 0,
        .gpio_num   = NET_LED_GPIO,
        .speed_mode = LEDC_MODE,
        .timer_sel  = LEDC_TIMER
    };
    if (ledc_channel_config(&ledc_channel_net) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to configure PWM channel for NET LED");
        return;
    }

    ledc_channel_config_t ledc_channel_gps = {
        .channel    = LEDC_CHANNEL_GPS,
        .duty       = 0,
        .gpio_num   = GPS_LED_GPIO,
        .speed_mode = LEDC_MODE,
        .timer_sel  = LEDC_TIMER
    };
    if (ledc_channel_config(&ledc_channel_gps) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to configure PWM channel for GPS LED");
        return;
    }

    // 初始化LED控制结构体
    memset(leds, 0, sizeof(leds));
    leds[LED_NET_STATE].channel = LEDC_CHANNEL_NET;
    leds[LED_GPS_STATE].channel = LEDC_CHANNEL_GPS;
    ESP_LOGI(TAG, "LED driver initialized");
}

void led_set_state(led_type_t led, led_state_t state) {
    if (led > LED_GPS_STATE) {
        ESP_LOGE(TAG, "Invalid LED type: %d", led);
        return;
    }
    leds[led].state = state;
    leds[led].last_toggle = xTaskGetTickCount();
    ESP_LOGI(TAG, "LED %d state set to %d", led, state);

    switch (state) {
        case LED_OFF:
            ledc_set_duty(LEDC_MODE, leds[led].channel, 0);
            ledc_update_duty(LEDC_MODE, leds[led].channel);
            break;
        case LED_ON:
            ledc_set_duty(LEDC_MODE, leds[led].channel, (1 << LEDC_DUTY_RES) - 1);
            ledc_update_duty(LEDC_MODE, leds[led].channel);
            break;
        case LED_BREATH:
            leds[led].breath_duty = 0;
            leds[led].breath_direction = 1;
            break;
        default:
            break;
    }
}

void led_task_start(void) {
    if (led_task_handle == NULL) {
        if (xTaskCreate(led_task, "led_ctrl", 2048, NULL, 5, &led_task_handle) != pdPASS) {
            ESP_LOGE(TAG, "Failed to create LED task");
        } else {
            ESP_LOGI(TAG, "LED task started");
        }
    }
}

void led_task_stop(void) {
    if (led_task_handle != NULL) {
        vTaskDelete(led_task_handle);
        led_task_handle = NULL;
        ESP_LOGI(TAG, "LED task stopped");
    } else {
        ESP_LOGE(TAG, "LED task handle is NULL");
    }
}